<?
class ImageEditor
{
  var $img;  
  var $w;
  var $h;
  var $type;
  
  var $font;
  var $color;
  var $size;
  
  var $quality;
  
  var $error;
  

  function ImageEditor()
  {
    $this->font  = false;
    $this->error = false;
    $this->size  = 12;
    $this->quality = 100;
  }

  function createImage($w,$h)
  {
     $this->type = "jpg";
     $this->w = $w; 
     $this->h = $h;
     $this->img = @imagecreatetruecolor($this->w, $this->h);    
  }
  
  function fill($R,$G,$B)
  {
     ImageFill($this->img, 0, 0, ImageColorAllocate($this->img, $R, $G, $B));
  }

  function loadImageFromFile($filename)
  {
      if(!file_exists($filename))
      {
         $this->error = true;
         return false;
      }
      
      $img = false;
      
      $type = strtolower(end(explode('.', $filename)));
      if ($type == 'jpg' || $type == 'jpeg') 
      {
        $img = @imagecreatefromjpeg($filename);
      }else if ($type == 'png') 
      {
        $img = @imagecreatefrompng($filename);
      }else if ($type == 'gif')
      {
        $img = @imagecreatefromgif($filename);
      }      
      return $img;
  }
  
  function loadImage($filename)
  {
      $this->img = $this->loadImageFromFile($filename);
      if(!$this->img)
      {
         $this->error = true;
         return false;          
      }
      
      $this->type = strtolower(end(explode('.', $filename)));
      if ($this->type == 'gif')
      {
        $handle   = fopen($filename, "r");
        $contents = fread($handle, 6);
        fclose($handle);
        if (strtoupper($contents)=="GIF89A") //animated gif
        {    		
          $this->type = "ani_gif";
        }
      }
            
      $this->w = $this->getImageWidth($this->img);
      $this->h = $this->getImageHeight($this->img);
  }
  
  //$quality for JPG
  function outputFile($filename,$img_type="",$quality=100)
  {
    if($img_type!="") $this->type = $img_type;
    
    if ($this->type == 'jpg' || $this->type == 'jpeg')
    {
      imagejpeg($this->img,$filename,$quality);
    }else if ($this->type == 'png')
    {
      imagepng($this->img, $filename);
    }else if ($this->type == 'gif') 
    {
      imagegif($this->img,$filename);
    }
  }

  function outputStream($img_type="")
  {
    if($img_type!="") $this->type = $img_type;
    
    if ($this->type == 'jpg' || $this->type == 'jpeg')
    {
      imagejpeg($this->img);
    }else if ($this->type == 'png') 
    {
      imagepng($this->img);
    }else if ($this->type == 'gif') 
    {
      imagegif($this->img);
    }
  }

  function getImageWidth($img)
  {
      return imagesx($img);
  }

  function getImageHeight($img)
  {
      return imagesy($img);     
  }
  
  function resize($width, $height) 
  {
    if(!$this->error) 
    {
      $tmpimage = imagecreatetruecolor($width, $height);
      imagecopyresampled($tmpimage, $this->img, 0, 0, 0, 0, $width, $height, $this->w, $this->h);
      imagedestroy($this->img);
      $this->img = $tmpimage;
      $this->w = $width;
      $this->h = $height;
    }
  }
    
  function crop($x, $y, $width, $height) 
  {
    if(!$this->error) 
    {
      $tmpimage = imagecreatetruecolor($width, $height);
      imagecopyresampled($tmpimage, $this->img, 0, 0, $x, $y, $width, $height, $width, $height);
      imagedestroy($this->img);
      $this->img = $tmpimage;
      $this->w = $width;
      $this->h = $height;
    }
  }

  function thumbnail($src_fname,$dst_fname,$thumb_width,$thumb_height,$crop=false)
  {
     $this->loadImage($src_fname);
     
     if(!$this->error)
     {
           //ratio of width/height 
           $thumb_ratio = round($thumb_width/$thumb_height, 2); 
           list($width, $height, $type, $attr) = getimagesize($src_fname); 
           //get ratio of width/height 
           $ratio = round($width/$height, 2);
      
           if($width<=$thumb_width && $height<=$thumb_height) 
           {
          		copy($src_fname,$dst_fname);
          		$ret[] = $width;
          		$ret[] = $height;
        		  return $ret;
           }
      
           if($ratio > $thumb_ratio)
           { 
                //picture is too wide so we will set the the width to its maximum 
                $new_width = $thumb_width; 
                $new_height = ceil(($thumb_width*$height)/$width); 
           } elseif($ratio < $thumb_ratio)
           { 
                //picture is too high so we will set the height to its maximum 
                $new_width = ceil(($thumb_height*$width)/$height); 
                $new_height = $thumb_height; 
           } else 
           { 
                //the ratio of the image is the same as the thumbnail 
                $new_width  = $thumb_width; 
                $new_height = $thumb_height; 
           }
           
           if($this->type=="ani_gif")
           {
          		copy($src_fname,$dst_fname);
          		$ret[] = $new_width;
          		$ret[] = $new_height;
          		return $ret;
           }
      
           if($crop)
           {
                //determine the width and height to keep the thumbnail uniform 
                //then crop the thumbnail in the center to get our new thumbnail 
                if($ratio > $thumb_ratio)
                {
                    //picture is too wide so we will need to crop the thumbnails width 
                    $new_width = ceil(($width*$thumb_width)/$height); 
                    $new_height = $thumb_height; 
                    $crop_x = (round($new_width/2))-(round($thumb_width/2)); 
                    $crop_y = 0; 
                } elseif($ratio < $thumb_ratio)
                { 
                  //picture is too high so we will need to crop the thumbnails height 
                  $new_width = $thumb_width; 
                  $new_height = ceil(($height*$thumb_height)/$width); 
                  $crop_x = 0; 
                  $crop_y = (round($new_height/2))-(round($thumb_height/2)); 
                } else 
                { 
                    //the ratio of the image is the same as the thumbnail 
                    $new_width = $thumb_width; 
                    $new_height = $thumb_height; 
                    $crop_x = 0; 
                    $crop_y = 0; 
                }
        
               //resize 
               $this->resize($new_width, $new_height);
               //crop 
               $this->crop($crop_x, $crop_y, $thumb_width, $thumb_height); 
           }else
           {
               //resize 
               $this->resize($new_width, $new_height);
           }

          $this->outputFile($dst_fname);
                                
       		$ret[] = $this->w;
       		$ret[] = $this->h;
       		return $ret;
     }else
     {
        return NULL;     
     }
  } 

  function setFont($font) {
    $this->font = $font;
  }

  function setSize($size) {
    $this->size = $size;
  }
  
  function getFontWidth()
  {
    return imagefontwidth($this->size);  
  }

  function addText($str, $x, $y, $angle, $R,$G,$B)
  {
    if(!$this->error) 
    {
      if($this->font) 
      {
        $color = ImageColorAllocate($this->img, $R,$G,$B);
        if(!imagettftext($this->img, $this->size, $angle, $x, $y, $color, $this->font, $str)) 
        {
          $this->font = false;
          $this->error = true;
        }
      }else 
      {
        $color = ImageColorAllocate($this->img, $R,$G,$B);
        Imagestring($this->img, 5, $x, $y, $str, $color);
      }
    }
  }

  function addImage($filename,$dst_x,$dst_y)
  {
      $src_im = $this->loadImageFromFile($filename);
      if(!$src_im)
      {
          //image was not loaded
          return;  
      }else
      {    
          $src_w  = imagesx($src_im);
          $src_h  = imagesy($src_im);          
          $this->copyImage($src_im,$dst_x,$dst_y,0,0,$src_w,$src_h);              
      }
  }

  function copyImage($src_im,$dst_x,$dst_y,$src_x,$src_y,$src_w,$src_h)
  {
          imagecopy($this->img,$src_im,$dst_x,$dst_y,$src_x,$src_y,$src_w,$src_h);    
  }
  
  
  function captcha($width,$height,$x_pos,$y_pos,$offset,$num_digits,$background,$font = "arial.ttf")
  {     
     $this->loadImage($background);
     if(!$this->error)
     {
        srand ((float) microtime() * 10000000);
        $s_code ="";   
        $x = $x_pos;
        $y = $y_pos;
        
        $this->setFont($font);
        
        for($i = 0;$i<$num_digits;$i++)
        {
          $n = rand(0,9);
          $size       = rand(14, 20);
          $angle      = rand(-30, 30);
          $k          = rand(0,6);
          switch($k)
          {
            case 0: $this->addText($n, $x, $y, $angle, 224, 167, 192); break;
            //case 1: $this->addText($n, $x, $y, $angle, 222, 226, 255); break;
			case 1: $this->addText($n, $x, $y, $angle, 222, 100, 40); break;
            case 2: $this->addText($n, $x, $y, $angle, 255, 123, 51);  break;
            case 3: $this->addText($n, $x, $y, $angle, 12,134, 26);    break;
            case 4: $this->addText($n, $x, $y, $angle, 255, 204, 0);   break;
            case 5: $this->addText($n, $x, $y, $angle, 255, 44, 9);    break;
            case 6: $this->addText($n, $x, $y, $angle, 142, 142, 142); break;
          }  
          $s_code .= $n;
          $x += $offset;
        }
        $this->outputStream("jpg");        
        return $s_code;
     }  
  } 

  function html2rgb($color)
  {    
     if ($color[0] == '#')    $color = substr($color, 1);    
     if (strlen($color) == 6) 
     list($r, $g, $b) = array($color[0].$color[1], $color[2].$color[3], $color[4].$color[5]);    
     elseif (strlen($color) == 3) list($r, $g, $b) = array($color[0].$color[0], $color[1].$color[1], $color[2].$color[2]);
     else return false;    
     $r = hexdec($r); 
     $g = hexdec($g); 
     $b = hexdec($b);    
     return array($r, $g, $b);
  }
  
  function drawLine($x1, $y1, $x2, $y2, $color, $thick = 1) {
    /* this way it works well only for orthogonal lines
    imagesetthickness($image, $thick);
    return imageline($image, $x1, $y1, $x2, $y2, $color);
    */
    if ($thick == 1) {
        return imageline($this->img, $x1, $y1, $x2, $y2, $color);
    }
    $t = $thick / 2 - 0.5;
    if ($x1 == $x2 || $y1 == $y2) {
        return imagefilledrectangle($this->img, round(min($x1, $x2) - $t), round(min($y1, $y2) - $t), round(max($x1, $x2) + $t), round(max($y1, $y2) + $t), $color);
    }
    $k = ($y2 - $y1) / ($x2 - $x1); //y = kx + q
    $a = $t / sqrt(1 + pow($k, 2));
    $points = array(
        round($x1 - (1+$k)*$a), round($y1 + (1-$k)*$a),
        round($x1 - (1-$k)*$a), round($y1 - (1+$k)*$a),
        round($x2 + (1+$k)*$a), round($y2 - (1-$k)*$a),
        round($x2 + (1-$k)*$a), round($y2 + (1+$k)*$a),
    );
    imagefilledpolygon($this->img, $points, 4, $color);
    return imagepolygon($this->img, $points, 4, $color);
  }
}    
?>
